iT邦幫忙

0

[react] 使用kendo ui 建立資料表--part2

  • 分享至 

  • xImage
  •  

承接part1,資料顯示完後,當然下一步就是進行增刪改了!

實踐

更改src/dataTable.js

  • 初始化調整
  constructor(props) {
    super(props);
    this.booleanCell = this.booleanCell.bind(this); // cell ui
    this.rowEdit = this.rowEdit.bind(this);  // 編輯資料事件
    this.itemChange = this.itemChange.bind(this); // 資料更動事件
    this.exitEdit = this.exitEdit.bind(this); // 離開編輯資料事件
    this.onSaveClick = this.onSaveClick.bind(this); // 儲存按鈕事件
    this.onCancelClick = this.onCancelClick.bind(this); // 取消更動按鈕事件
    this.onAddClick = this.onAddClick.bind(this); // 新增按鈕事件
    this.state = {
      gridData: JSON.parse(JSON.stringify(products)), // deep copy
      saveGridData: JSON.parse(JSON.stringify(products)), // deep copy
      changed: false, // 內文是否有被更動過
      editItem: null // 保存當前編輯行
    };
  }
  • 調整state初始值,關於deep copy 可以參考這篇,若不使用deep copy將會使saveGridData與gridData映射到相同元素。
this.state = {
  gridData: JSON.parse(JSON.stringify(products)), // deep copy
  saveGridData: JSON.parse(JSON.stringify(products)), // deep copy
  changed: false, // 內文是否有被更動過
  editItem: null // 保存當前編輯行
};
  • 調整 render
render() {
    return (
      <Grid
        style={{ height: '400px', width: '970px' }}
        data={this.state.gridData}
        onRowClick={this.rowEdit}
        onItemChange={this.itemChange}
        editField='inEdit'
      >
        <GridToolbar>
          <div onClick={this.exitEdit}>
            <button onClick={this.onSaveClick} disabled={!this.state.changed}>
              Save
            </button>
            <button onClick={this.onCancelClick} disabled={!this.state.changed}>
              Cancel
            </button>
            <button onClick={this.onAddClick}>
              Add new
            </button>
          </div>
        </GridToolbar >
        <Column field='ProductID' title='ID' width='85px' editable={false}/> // 不可更動
        <Column field='ProductName' title='Product Name' width='200px' />
        <Column field='UnitsInStock' title='Units In Stock' width='180px' editor='numeric'/> // 定義資料型態
        <Column field='Discontinued' width='180px' cell={this.booleanCell} />
        <Column field='Category.CategoryName' title='CategoryName' width='200px' />
        <Column title="Edit"  width='120px' cell={this.onDeleteItem}/>
      </Grid>
    );
  }
  • 定義cell顯示內文,當編輯該行時,回傳可編輯元件
  booleanCell = (props) => {
    return (props.dataItem.inEdit) ? (
      <td>
        <input
          onChange={
            (event) => {
              const obj = this.state.gridData;
              const index = obj.findIndex((o) => {return props.dataItem.ProductID === o.ProductID;});
              obj[index][props.field] = event.target.checked;
              this.setState({ gridData: obj, changed: true });
            }
          }
          type='checkbox'
          checked={props.dataItem[props.field]} />
      </td>
    ) : (
      <td>
        <input disabled type='checkbox' checked={props.dataItem[props.field]} />
      </td>
    );
  }
  • 定義刪除行按鈕
  onDeleteItem=(eventItem)=>{
    return (<td>
      <button onClick={()=>{
        const data = this.state.gridData;
        const delIndex = data.findIndex(p => {return p.ProductID === eventItem.dataItem.ProductID;});
        if (delIndex >-1){
          if(window.confirm('Press a button')){
            data.splice(delIndex,1);
            this.setState({gridData: data, changed: true});
          }
        }
      }}>
        remove
      </button>
    </td>);
  }
  • 儲存按鈕事件
  onSaveClick = () => {
    const datas = this.state.gridData.map(
      (d) => {
        const data = d;
        data.inEdit = false;
        return data;
      }
    );
    this.setState(
      {
        saveGridData: JSON.parse(JSON.stringify(datas)),
        editItem: null,
        changed: false
      }
    ); // deep copy
  };
  • 取消更動按鈕事件
  onCancelClick = () => {
    const datas = this.state.saveGridData.map(
      (d) => {
        const data = d;
        data.inEdit = false;
        return data;
      }
    );
    this.setState(
      {
        gridData: JSON.parse(JSON.stringify(datas)),
        editItem: null,
        changed: false
      }
    ); // deep copy
  };
  • 新增按鈕事件
  onAddClick = () => {
    const newItem = this.state.gridData.map(
      (d) => {
        const data = d;
        data.inEdit = false;
        return data;
      }
    );
    newItem.push({
      ProductID: findMaxId(this.state.gridData) + 1,
      ProductName: '',
      Discontinued: false,
      Category: {
        CategoryID: 0,
        CategoryName: ''
      },
      inEdit: true
    });
    this.setState({ gridData: newItem, changed: true });
  }
  • 資料更動事件
  itemChange = (event) => {
    const obj = this.state.gridData;
    const index = obj.findIndex((o) => { return event.dataItem.ProductID === o.ProductID; });
    obj[index] = editJson(obj[index], event.field, event.value);
    this.setState({ gridData: obj, changed: true });
  }
  • 編輯資料事件
  rowEdit = (e) => {
    if (this.state.editItem === e.dataItem.ProductID) {
      return;
    }
    const data = this.state.gridData.map((item) => {
      const result = item;
      result.inEdit = item.ProductID === e.dataItem.ProductID;
      return result;
    });
    this.setState({
      editItem: e.dataItem.ProductID,
      gridData: data
    });
  }
  • 離開編輯資料事件
  exitEdit = (event) => {
    if (event.target === event.currentTarget) {
      const datas = this.state.gridData.map(
        (d) => {
          const data = d;
          data.inEdit = false;
          return data;
        }
      );
      this.setState({
        data: datas,
        editItem: null
      });
    }
  }
  • 自定義函數
// 利用field設定json的屬性值
const editJson = (json, field, value) => {
  const jsonArray = json;
  const fields = field.split('.');
  jsonArray[fields[0]] = (fields.length === 1) ? value : editJson(json[fields[0]], fields.slice(1).join('.'), value);
  return jsonArray;
};
// 取得ProductID最大值
const findMaxId = (datas) => {
  let result = 0;
  datas.forEach((data) => {
    if (result < data.ProductID) {
      result = data.ProductID;
    }
  });
  return result;
};

一樣只要執行npm start就可以看到我們的資料表了!
順帶附上github給大家參考

結輪

使用button新增資料行,來進行資料的新增。
在資料行中新增刪除button,將該筆資料進行刪除。
利用Grid的onRowClick事件與editField,進行編輯資料表,再透過onItemChange事件將資料修改進行儲存,達到我們對資料的修改。
這樣就可以進行資料的增刪改了!


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言